package com.jhf.youke.core.utils;

import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.RandomStringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符串工具类, 继承org.apache.commons.lang3.StringUtils类
 * @author ThinkGem
 * @version 2013-05-22
 */
public class StringUtils extends org.apache.commons.lang3.StringUtils {

	private static final char SEPARATOR = '_';
	private static final String CHARSET_NAME = "UTF-8";

	private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

	private static Pattern CHAR_PATTERN = Pattern.compile("<([a-zA-Z]+)[^<>]*>");

	private static final Random RANDOM = new SecureRandom();
	/**
	 * 截取末位特殊字符 将最后一位,去掉 如 1，2，3， 转换为 1，2，3
	 **/
	public static String cutSpecialChar(String str, String c) {
		if (str != null && c != null && str.length()>=1) {
			if (c.equals(str.substring(str.length() - 1, str.length()))) {
				str = str.substring(0, str.lastIndexOf(c));
			}
		}
		return str;
	}

	public static String substringBefore(String str, String separator) {
		if (!isEmpty(str) && separator != null) {
			if (separator.isEmpty()) {
				return "";
			} else {
				int pos = str.indexOf(separator);
				return pos == -1 ? str : str.substring(0, pos);
			}
		} else {
			return str;
		}
	}

	public static String substringAfter(String str, String separator) {
		if (isEmpty(str)) {
			return str;
		} else if (separator == null) {
			return "";
		} else {
			int pos = str.indexOf(separator);
			return pos == -1 ? "" : str.substring(pos + separator.length());
		}
	}

	/**
	 * 类的方法定义: chgNull(); 方法的说明: 将 String 对象转换 如果对象为Null转换为""字符串
	 *
	 * @param source
	 *            被处理的字符串
	 * @return 处理后的字符串
	 */
	public static String chgNull(Object source) {
		String result = "";
		if (source != null) {
			result = source.toString();
		}
		return result;
	}

	public static String chgNull(String source) {
		String result = "";
		if (source != null){
			result = source.toString().trim();
		}
		return result;
	}

	/**
	 * 类的方法定义: chgZero(); 方法的说明: 将 String 对象转换 如果对象为Null转换为"0"字符串,用于数字
	 *
	 * @param source
	 *            被处理的字符串
	 * @return 处理后的字符串
	 */
	public static String chgZero(Object source) {
		String result = "0";
		if(chgNull(source).length() > 0) {
			result = source.toString();
		}
		return result;
	}

	/**
	 * 类的方法定义: chgZero(); 方法的说明: 将 String 对象转换 如果对象为Null转换为"0"字符串,用于数字
	 *
	 * @param source
	 *            被处理的字符串
	 * @return 处理后的字符串
	 */
	public static String chgNullToNum(Object source, String number) {
		String result = "0";
		if(chgNull(number).length()>0){
			result = number;
		}

		if(chgNull(source).length() > 0){
			result = source.toString();
		}

		return result;
	}



	/**
	 * 转换为字节数组
	 * @param str
	 * @return
	 */
	public static byte[] getBytes(String str){
		if (str != null){
			try {
				return str.getBytes(CHARSET_NAME);
			} catch (UnsupportedEncodingException e) {
				return null;
			}
		}else{
			return null;
		}
	}

	/**
	 * 转换为字节数组
	 * @param bytes
	 * @return
	 */
	public static String toString(byte[] bytes){
		try {
			return new String(bytes, CHARSET_NAME);
		} catch (UnsupportedEncodingException e) {
			return EMPTY;
		}
	}

	/**
	 * 是否包含字符串
	 * @param str 验证字符串
	 * @param strs 字符串组
	 * @return 包含返回true
	 */
	public static boolean inString(String str, String... strs){
		if (str != null){
			for (String s : strs){
				if (str.equals(trim(s))){
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 替换掉HTML标签方法
	 */
	public static String replaceHtml(String html) {
		if (isBlank(html)){
			return "";
		}
		String regEx = "<.+?>";
		Pattern p = Pattern.compile(regEx);
		Matcher m = p.matcher(html);
		String s = m.replaceAll("");
		return s;
	}

	/**
	 * 替换为手机识别的HTML，去掉样式及属性，保留回车。
	 * @param html
	 * @return
	 */
	public static String replaceMobileHtml(String html){
		if (html == null){
			return "";
		}
		return html.replaceAll("<([a-z]+?)\\s+?.*?>", "<$1>");
	}

	/**
	 * 替换为手机识别的HTML，去掉样式及属性，保留回车。
	 * @param txt
	 * @return
	 */
	public static String toHtml(String txt){
		if (txt == null){
			return "";
		}
		return replace(replace(Encodes.escapeHtml(txt), "\n", "<br/>"), "\t", "&nbsp; &nbsp; ");
	}


	public static String abbr2(String param, int length) {
		if (param == null) {
			return "";
		}
		StringBuffer result = new StringBuffer();
		int n = 0;
		char temp;
		// 是不是HTML代码
		boolean isCode = false;
		// 是不是HTML特殊字符,如&nbsp;
		boolean isHtml = false;
		for (int i = 0; i < param.length(); i++) {
			temp = param.charAt(i);
			if (temp == '<') {
				isCode = true;
			} else if (temp == '&') {
				isHtml = true;
			} else if (temp == '>' && isCode) {
				n = n - 1;
				isCode = false;
			} else if (temp == ';' && isHtml) {
				isHtml = false;
			}
			try {
				if (!isCode && !isHtml) {
					n += String.valueOf(temp).getBytes("GBK").length;
				}
			} catch (UnsupportedEncodingException e) {
				e.getMessage();
			}

			if (n <= length - 3) {
				result.append(temp);
			} else {
				result.append("...");
				break;
			}
		}
		// 取出截取字符串中的HTML标记
		String tempResult = result.toString().replaceAll("(>)[^<>]*(<?)",
				"$1$2");
		// 去掉不需要结素标记的HTML标记
		tempResult = tempResult
				.replaceAll(
						"</?(AREA|BASE|BASEFONT|BODY|BR|COL|COLGROUP|DD|DT|FRAME|HEAD|HR|HTML|IMG|INPUT|ISINDEX|LI|LINK|META|OPTION|P|PARAM|TBODY|TD|TFOOT|TH|THEAD|TR|area|base|basefont|body|br|col|colgroup|dd|dt|frame|head|hr|html|img|input|isindex|li|link|meta|option|p|param|tbody|td|tfoot|th|thead|tr)[^<>]*/?>",
						"");
		// 去掉成对的HTML标记
		tempResult = tempResult.replaceAll("<([a-zA-Z]+)[^<>]*>(.*?)</\\1>",
				"$2");
		// 用正则表达式取出标记
		Matcher m = CHAR_PATTERN.matcher(tempResult);
		List<String> endHtml = Lists.newArrayList();
		while (m.find()) {
			endHtml.add(m.group(1));
		}
		// 补全不成对的HTML标记
		for (int i = endHtml.size() - 1; i >= 0; i--) {
			result.append("</");
			result.append(endHtml.get(i));
			result.append(">");
		}
		return result.toString();
	}

	/**
	 * 转换为Double类型
	 */
	public static Double toDouble(Object val){
		if (val == null){
			return 0D;
		}
		try {
			return Double.valueOf(trim(val.toString()));
		} catch (Exception e) {
			return 0D;
		}
	}

	/**
	 * 转换为Float类型
	 */
	public static Float toFloat(Object val){
		return toDouble(val).floatValue();
	}

	/**
	 * 转换为Long类型
	 */
	public static Long toLong(Object val){
		if(ifNull(val)){
			return null;
		}
		return  Long.valueOf(val.toString());
	}

	/**
	 * 转换为Integer类型
	 */
	public static Integer toInteger(Object val){
		return toLong(val).intValue();
	}

	/**
	 * 获得用户远程地址
	 */
	public static String getRemoteAddr(HttpServletRequest request){
		String remoteAddr = request.getHeader("X-Real-IP");
		if (isNotBlank(remoteAddr)) {
			remoteAddr = request.getHeader("X-Forwarded-For");
		}else if (isNotBlank(remoteAddr)) {
			remoteAddr = request.getHeader("Proxy-Client-IP");
		}else if (isNotBlank(remoteAddr)) {
			remoteAddr = request.getHeader("WL-Proxy-Client-IP");
		}
		return remoteAddr != null ? remoteAddr : request.getRemoteAddr();
	}

	/**
	 * 驼峰命名法工具
	 * @return
	 * 		toCamelCase("hello_world") == "helloWorld"
	 * 		toCapitalizeCamelCase("hello_world") == "HelloWorld"
	 * 		toUnderScoreCase("helloWorld") = "hello_world"
	 */
	public static String toCamelCase(String s) {
		if (s == null) {
			return null;
		}

		s = s.toLowerCase();

		StringBuilder sb = new StringBuilder(s.length());
		boolean upperCase = false;
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);

			if (c == SEPARATOR) {
				upperCase = true;
			} else if (upperCase) {
				sb.append(Character.toUpperCase(c));
				upperCase = false;
			} else {
				sb.append(c);
			}
		}

		return sb.toString();
	}

	/**
	 * 驼峰命名法工具
	 * @return
	 * 		toCamelCase("hello_world") == "helloWorld"
	 * 		toCapitalizeCamelCase("hello_world") == "HelloWorld"
	 * 		toUnderScoreCase("helloWorld") = "hello_world"
	 */
	public static String toCapitalizeCamelCase(String s) {
		if (s == null) {
			return null;
		}
		s = toCamelCase(s);
		return s.substring(0, 1).toUpperCase() + s.substring(1);
	}

	/**
	 * 驼峰命名法工具
	 * @return
	 * 		toCamelCase("hello_world") == "helloWorld"
	 * 		toCapitalizeCamelCase("hello_world") == "HelloWorld"
	 * 		toUnderScoreCase("helloWorld") = "hello_world"
	 */
	public static String toUnderScoreCase(String s) {
		if (s == null) {
			return null;
		}

		StringBuilder sb = new StringBuilder();
		boolean upperCase = false;
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);

			boolean nextUpperCase = true;

			if (i < (s.length() - 1)) {
				nextUpperCase = Character.isUpperCase(s.charAt(i + 1));
			}

			if ((i > 0) && Character.isUpperCase(c)) {
				if (!upperCase || !nextUpperCase) {
					sb.append(SEPARATOR);
				}
				upperCase = true;
			} else {
				upperCase = false;
			}

			sb.append(Character.toLowerCase(c));
		}

		return sb.toString();
	}

	/**
	 * 转换为JS获取对象值，生成三目运算返回结果
	 * @param objectString 对象串
	 *   例如：row.user.id
	 *   返回：!row?'':!row.user?'':!row.user.id?'':row.user.id
	 */
	public static String jsGetVal(String objectString){
		StringBuilder result = new StringBuilder();
		StringBuilder val = new StringBuilder();
		String[] vals = split(objectString, ".");
		for (int i=0; i<vals.length; i++){
			val.append("." + vals[i]);
			result.append("!"+(val.substring(1))+"?'0':");
		}
		result.append(val.substring(1));
		return result.toString();
	}

	/**
	 * 随即生成指定位数的含验证码字符串
	 *
	 * @author Peltason
	 *
	 * @date 2007-5-9
	 * @param bit
	 *            指定生成验证码位数
	 * @return String
	 */
	public static String random(int bit) {
		if (bit == 0){
			bit = 6;
		}
		// 因为o和0,l和1很难区分,所以,去掉大小写的o和l 初始化种子
		String str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz";
		// 返回6位的字符串
		return RandomStringUtils.random(bit, str);
	}

	/**
	 * 手机号
	 * */
	public static boolean isMobileNo(String phone) {
		int initNum = 11;
		String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$";
		if (phone.length() != initNum) {
			return false;
		} else {
			Pattern p = Pattern.compile(regex);
			Matcher m = p.matcher(phone);
			boolean isMatch = m.matches();
			return isMatch;
		}
	}

//	public static boolean isMobileNo(String mobiles){
//		Pattern p = Pattern.compile("^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(17[013678])|(18[0,5-9]))\\d{8}$");
//		Matcher m = p.matcher(mobiles);
//		return m.matches();
//	}

	/**
	 * 把html内容转为文本
	 * @param html 需要处理的html文本	 *
	 * @return
	 */
	public static String trimHtml2Txt(String html){
		//去掉head
		html = html.replaceAll("\\<head>[\\s\\S]*?</head>(?i)", "");
		html = html.replaceAll("\\<!--[\\s\\S]*?-->", "");
		html = html.replaceAll("\\<![\\s\\S]*?>", "");
		html = html.replaceAll("\\<style[^>]*>[\\s\\S]*?</style>(?i)", "");
		html = html.replaceAll("\\<script[^>]*>[\\s\\S]*?</script>(?i)", "");
		html = html.replaceAll("\\<w:[^>]+>[\\s\\S]*?</w:[^>]+>(?i)", "");
		html = html.replaceAll("\\<xml>[\\s\\S]*?</xml>(?i)", "");
		html = html.replaceAll("\\<html[^>]*>|<body[^>]*>|</html>|</body>(?i)", "");
		html = html.replaceAll("\\\r\n|\n|\r", " ");
		html = html.replaceAll("\\<br[^>]*>(?i)", "\n");
    	html = html.replaceAll("\\</p>(?i)", "\n");
		html = html.replaceAll("\\<[^>]+>", "");
		html = html.replaceAll("\\ ", " ");
		return html.trim();
	}

	/**
	 * 获取随机字符串 Nonce Str
	 * @return String 随机字符串
	 */
	public static String generateNonceStr() {
		char[] nonceChars = new char[32];
		for (int index = 0; index < nonceChars.length; ++index) {
			nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
		}
		return new String(nonceChars);
	}



	public static Boolean ifNull(Object source) {
		String result = chgNull(source);
		return StringUtils.isEmpty(result);
	}

	public static Boolean chgBoolean(Object source) {
		String result = chgNull(source);
		if(StringUtils.isEmpty(result)){
			return null;
		}
		return Boolean.getBoolean(result);
	}

	/**
	 *	隐藏名称，例如：将"王小二"变为"王**"
	 * @param fullName
	 * @return
	 */
	public static String hideName(String fullName){
		String name = StringUtils.left(fullName, 1);
		return StringUtils.rightPad(name, StringUtils.length(fullName), "*");
	}

	/**
	 * 隐藏字符串
	 * @param source	字符串
	 * @param leftNum 	左边几位不隐藏
	 * @param hideNum	隐藏几位
	 * @return	例如：hideString("湖南长沙市", 1, 2) 变为 ""湖**沙市
	 */
	public static String hideString(String source, int leftNum, int hideNum){
		return StringUtils.left(source, leftNum).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(source, source.length()-(hideNum+3)), StringUtils.length(source), "*"), "***"));
	}

	/**
	 * 生成随机姓名
	 */
	public static String getRandomName(){
		String[] names = {"朱","孔","魏","范","鲁","马","谢","方","杨","李","王","郑","周","刘","吴","张","熊","纪","舒","屈"};

		String name = names[(int)(new Random().nextInt() * 20)];
		int b = (int)(Math.random() * 2 + 1);
		for(int j=0;j<b;j++){
			name += "*";
		}
		return name;
	}


	public static String addZeroForNum(String str, int strLength) {
		int strLen = str.length();
		if (strLen < strLength) {
			while (strLen < strLength) {
				StringBuffer sb = new StringBuffer();
				sb.append(str).append("0");
				str = sb.toString();
				strLen = str.length();
			}
		}

		return str;
	}

	/**
	 * 手机号码中间四位变为*号
	 * @param phone
	 * @return
	 */
	public static String starPhone(String phone) {
		if(!StringUtils.ifNull(phone)) {
			String hidenPhone = phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
			return hidenPhone;
		}else {
			return phone;
		}
	}

	/**
	 * 是否为http(s)://开头
	 *
	 * @param link 链接
	 * @return 结果
	 */
	public static boolean ishttp(String link) {
		return StringUtils.startsWithAny(link, Constant.HTTP, Constant.HTTPS);
	}

	public static void main(String[] args) throws Exception {
		String str = "123";
		str = addZeroForNum(str, 18);
		System.out.println(str);
	}

}
